package cn.ecpay.unionpay.settle.controller;

import cn.ecpay.unionpay.settle.Common.CommonUtil;
import cn.ecpay.unionpay.settle.Common.DateUtil;
import cn.ecpay.unionpay.settle.Common.RespCode;
import cn.ecpay.unionpay.settle.Common.UnionpayDict;
import cn.ecpay.unionpay.settle.dao.SingleQueryDao;
import cn.ecpay.unionpay.settle.entity.db.TPvFundSettleSingle;
import cn.ecpay.unionpay.settle.entity.db.TPvSingleQuery;
import cn.ecpay.unionpay.settle.util.CommonBase;
import cn.ecpay.unionpay.settle.util.FsasService;
import cn.ecpay.unionpay.settle.util.LogUtil;
import cn.ecpay.unionpay.settle.util.SDKConfig;
import org.rex.db.exception.DBException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 单笔查询
 * Created by zhaoyanzeng on 2018/11/6.
 */
@RestController
public class SingleQueryController {

    @Resource
    private SingleQueryDao singleQueryDao;

    @RequestMapping(value = "/singleQuery", method = RequestMethod.POST)
    public String singleQuery(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        Map<String, String> contentData = convertContentData(req);
        if(isExistTxn(contentData.get("txnNo"),contentData.get("txnDate"))){
            return "重复交易";
        }
        TPvSingleQuery singleQuery = new TPvSingleQuery();
        Map<String, String> reqData = FsasService.sign(contentData,CommonBase.encoding); // 报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。

        reqDataConvert(singleQuery,reqData);

        String requestBackUrl = SDKConfig.getConfig().getBackRequestUrl(); // 交易请求url从配置文件读取对应属性文件fsas_sdk.properties中的
        Map<String, String> rspData = FsasService.doPost(reqData,requestBackUrl, CommonBase.encoding); // 发送请求报文并接受同步应答（默认连接超时时间30秒，读取返回结果超时时间30秒）;这里调用signData之后，调用submitUrl之前不能对submitFromData中的键值对做任何修改，如果修改会导致验签不通过
        rspDataConvert(singleQuery,rspData);
        StringBuffer parseStr = new StringBuffer("");
        if (!rspData.isEmpty()) {
            if (FsasService.validate(rspData, CommonBase.encoding)) {
                LogUtil.writeLog("验证签名成功");
                singleQuery.setRespValidate("1");
                String respCode = rspData.get("respCode");
                String origRespCode = rspData.get("origRespCode");
                if (("00").equals(respCode)) {
                    // 交易已受理(不代表交易已成功），等待接收后台通知更新订单状态,也可以主动发起 查询交易确定交易状态。
                    // TODO
                    if (("00").equals(origRespCode)) {
                        // 代表原交易成功 如不成功根据原交易应答码做相应处理
                        // TODO
                    } else if (("03").equals(origRespCode)
                            || ("05").equals(origRespCode)) {
                        // 订单处理中或交易状态未明，需稍后发起交易状态查询交易
                        // TODO
                    } else {
                        //其它根据需要作处理
                        // TODO
                    }
                } else {
                    // 其他应答码为失败请排查原因
                    // TODO
                }
            } else {
                LogUtil.writeErrorLog("验证签名失败");
                singleQuery.setRespValidate("0");
                // TODO 检查验证签名失败的原因
            }
        } else {
            // 未返回正确的http状态
            LogUtil.writeErrorLog("未获取到返回报文或返回http状态码非200");
        }
        try {
            singleQueryDao.insert(singleQuery);
        } catch (DBException e) {
            LogUtil.writeErrorLog("保存单笔查询失败");
            e.printStackTrace();
        }
        String reqMessage = CommonBase.genHtmlResult(reqData);
        String rspMessage = CommonBase.genHtmlResult(rspData);
        return "交易状态查询（单笔）请求报文:<br/>" + reqMessage + "<br/>" + "应答报文:</br>"
                + rspMessage + parseStr;
    }

    private Map<String, String> convertContentData(HttpServletRequest req) {
        String acqInsCode = req.getParameter("acqInsCode");
        String txnNo = req.getParameter("txnNo");
        String txnDate = req.getParameter("txnDate");
        String origTxnNo = req.getParameter("origTxnNo");
        String origTxnDate = req.getParameter("origTxnDate");
        String origTxnType = req.getParameter("origTxnType");

        Map<String, String> contentData = new HashMap<String, String>();

        /*** 银联资金结算接入系统，产品参数，除了encoding自行选择外其他不需修改 ***/
        contentData.put("version", CommonBase.version); // 版本号
        contentData.put("encoding", CommonBase.encoding); // 字符集编码
        // 可以使用UTF-8,GBK两种方式
        contentData.put("signMethod", SDKConfig.getConfig().getSignMethod()); // 签名方法
        contentData.put("txnType", UnionpayDict.TXN_TYPE_SINGLEQUERY); // 交易类型 05-交易状态查询（单笔）
        contentData.put("sndTime", CommonBase.getSendTime()); // 发送时间 格式HHmmss

        contentData.put("txnNo", txnNo); // 交易流水号
        contentData.put("acqInsCode", acqInsCode); // 机构代码
        contentData.put("txnDate", txnDate); // 交易日期
        contentData.put("origTxnType", origTxnType); // 原交易类型01：备款 02：商户资金结算
        // 04：回款
        contentData.put("origTxnNo", origTxnNo); // 原交易流水号
        contentData.put("origTxnDate", origTxnDate); // 原交易日期
//        contentData.put("backUrl", CommonBase.backUrl);
        return contentData;
    }


    //申请参数
    private void reqDataConvert(TPvSingleQuery singleQuery, Map<String, String> reqData) {
        singleQuery.setTxnNo(reqData.get("txnNo"));
        singleQuery.setAcqInsCode(reqData.get("acqInsCode"));
        singleQuery.setTxnType(reqData.get("txnType"));
        singleQuery.setTxnDate(reqData.get("txnDate"));
        singleQuery.setSndTime(reqData.get("sndTime"));
        singleQuery.setOrigTxnType(reqData.get("origTxnType"));
        singleQuery.setOrigTxnNo(reqData.get("origTxnNo"));
        singleQuery.setOrigTxnDate(reqData.get("origTxnDate"));

    }

    //同步返回结果
    private void rspDataConvert(TPvSingleQuery singleQuery,Map<String, String> rspData) {
        singleQuery.setRespCode(rspData.get("respCode"));
        singleQuery.setRespMsg(rspData.get("respMsg"));
        singleQuery.setPayeeAcctNo(rspData.get("payeeAcctNo"));
        singleQuery.setPayeeAcctName(rspData.get("payeeAcctName"));
        singleQuery.setCurrencyCode(rspData.get("currencyCode"));
        singleQuery.setTxnAmt(rspData.get("txnAmt"));
        singleQuery.setPayeeAcctBal(rspData.get("payeeAcctBal"));
        singleQuery.setAcctDate(rspData.get("acctDate"));
        singleQuery.setOrigRespCode(rspData.get("origRespCode"));
        singleQuery.setOrigRespMsg(rspData.get("origRespMsg"));
    }
    /**
     * 交易是否已存在
     *
     * @return
     */
    public boolean isExistTxn(String txnNo, String txnDate) {
        try {
            return singleQueryDao.isExistTxn(txnNo, txnDate);
        } catch (DBException e) {
            e.printStackTrace();
            return false;
        }
    }
}
